package com.xmutca.micro.uaa.security;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.io.UnsupportedEncodingException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.StringJoiner;

/**
 * Created by chunchengpeng on 17/7/27.
 */
@Slf4j
@Component
public class JwtTokenFactory {

    @Value("${micro.token.secret}")
    private String secret;

    @Value("${micro.token.expiration}")
    private long expiration;

    /**
     * 获取全部信息
     * @param token
     * @return
     */
    public Claims getClaimsFromToken(String token) {
        try {
            return Jwts.parser()
                    .setSigningKey(this.secret.getBytes("UTF-8"))
                    .parseClaimsJws(token)
                    .getBody();
        } catch (UnsupportedEncodingException e) {
            //其他错误
        } catch (Exception e) {
            //1. SignatureException, MalformedJwtException不可信息的jwt异常
            //2. ExpiredJwtException过期异常
            throw e;
        }
        return null;
    }

    /**
     * 生成token
     * @param details
     * @param request
     * @return
     */
    public String createToken(UserDetails details, HttpServletRequest request) {
        try {
            Map<String, Object> claimsMap = new HashMap<>();
            claimsMap.put("User-Agent", request.getHeader("User-Agent"));

            return Jwts.builder()
                    .setClaims(claimsMap)
                    .setSubject(details.getUsername()) // 设置主体用户对象
                    .setExpiration(new Date(System.currentTimeMillis() + expiration * 1000)) // 设置过期时间
                    .signWith(SignatureAlgorithm.HS512, this.secret.getBytes("UTF-8"))
                    .compact();
        } catch (UnsupportedEncodingException e) {
            //其他错误
        }
        return null;
    }

    /**
     * 令牌校验
     * @param claims
     * @param request
     * @return
     */
    public boolean validateToken(Claims claims, HttpServletRequest request) {
        String userAgent = request.getHeader("User-Agent");
        return userAgent.equals(claims.get("User-Agent", String.class));
    }
}
